#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>
#include "componentmanagerdialog.h"
#include "ui_componentmanagerdialog.h"

ComponentManagerDialog::ComponentManagerDialog(QWidget *parent, QSqlDatabase db)
    : QDialog(parent)
    , ui(new Ui::ComponentManagerDialog)
    , db_(db)
    , creatingTree(false)
{
    ui->setupUi(this);

    QSqlQuery query = db_.exec("select id, name from PRODUCT order by sortorder");
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }

    while (query.next()) {
        creatingTree = true;
        int prodid = query.value(0).toInt();
        QString prodName = query.value(1).toString();

        QTreeWidgetItem* pitem = new QTreeWidgetItem(ui->treeWidget, QStringList() << prodName);
        pitem->setData(0, Qt::UserRole, prodid);
        pitem->setFirstColumnSpanned(true);

        createComponentItems(pitem, -1);
        creatingTree = false;
    }
}

ComponentManagerDialog::~ComponentManagerDialog()
{
    delete ui;
}

void ComponentManagerDialog::createComponentItems(QTreeWidgetItem* pitem, int selectCompid)
{
    for (int i=pitem->childCount()-1; i>=0; --i) {
        QTreeWidgetItem* item = pitem->child(i);
        delete item;
    }

    int prodid = pitem->data(0, Qt::UserRole).toInt();
    QSqlQuery query = db_.exec( QString("select id, name, japaneseName from COMPONENT where prodid=%1 order by sortorder").arg(prodid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }

    creatingTree = true;
    while (query.next()) {
        int compid = query.value(0).toInt();
        QString compName = query.value(1).toString();
        QString jpName = query.value(2).toString();

        QTreeWidgetItem* citem = new QTreeWidgetItem(pitem, QStringList() << compName << jpName);
        citem->setData(0, Qt::UserRole, compid);
        citem->setFlags( citem->flags() | Qt::ItemIsEditable );
        if (compid == selectCompid)
            ui->treeWidget->setCurrentItem(citem, 0);
    }
    creatingTree = false;
}

void ComponentManagerDialog::on_addPushButton_clicked()
{
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if (item == NULL)
        return;

    QTreeWidgetItem* pitem;
    if (item->parent())
        pitem = item->parent();
    else
        pitem = item;
    int prodid = pitem->data(0, Qt::UserRole).toInt();

    QSqlQuery query = db_.exec( QString("select max(sortorder) from COMPONENT where prodid=%1").arg(prodid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }
    query.next();
    int sortorder = query.value(0).toInt() + 1;

    query = db_.exec( QString("insert into COMPONENT(prodid, sortorder) values(%1, %2)").arg(prodid).arg(sortorder) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }

    query = db_.exec( QString("select max(id) from COMPONENT") );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }
    query.next();
    int compid = query.value(0).toInt();

    QTreeWidgetItem* citem = new QTreeWidgetItem(pitem);
    citem->setData(0, Qt::UserRole, compid);
    citem->setFlags(citem->flags() | Qt::ItemIsEditable);
    ui->treeWidget->setCurrentItem(citem);
    ui->treeWidget->editItem(citem);
}

void ComponentManagerDialog::on_removePushButton_clicked()
{
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if (item == NULL || item->parent() == NULL)
        return;

    int id = item->data(0, Qt::UserRole).toInt();
    QString name = item->text(0);
    QMessageBox::StandardButton ret = QMessageBox::information(this, QString(), tr("Are you sure you want to delete selected component?\n\nName: %1").arg(name), QMessageBox::Ok|QMessageBox::Cancel);
    if (ret != QMessageBox::Ok)
        return;

    QSqlQuery query = db_.exec( QString("delete from COMPONENT where id=%1").arg(id) );
    if (query.lastError().isValid())
        qDebug() << query.lastError().text();

    delete item;
}

void ComponentManagerDialog::on_upPushButton_clicked()
{
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if (item == NULL || item->parent() == NULL)
        return;

    int prodid = item->parent()->data(0, Qt::UserRole).toInt();
    int compid = item->data(0, Qt::UserRole).toInt();

    db_.exec("BEGIN IMMEDIATE");

    // get current sortorder
    QSqlQuery query = db_.exec( QString("select sortorder from COMPONENT where id=%1").arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    if (query.next() == false) {
        db_.exec("ROLLBACK");
        return;
    }

    int sortorder = query.value(0).toInt();
    if (sortorder <= 1) {
        db_.exec("ROLLBACK");
        return;
    }

    // swap component
    query = db_.exec( QString("update COMPONENT set sortorder=%1 where sortorder=%2 and prodid=%3").arg(sortorder).arg(sortorder-1).arg(prodid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    query = db_.exec( QString("update COMPONENT set sortorder=%1 where id=%2").arg(sortorder-1).arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    db_.exec("COMMIT");

    createComponentItems(item->parent(), compid);
}

void ComponentManagerDialog::on_downPushButton_clicked()
{
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
    if (item == NULL || item->parent() == NULL)
        return;

    int prodid = item->parent()->data(0, Qt::UserRole).toInt();
    int compid = item->data(0, Qt::UserRole).toInt();

    db_.exec("BEGIN IMMEDIATE");

    // get current sortorder
    QSqlQuery query = db_.exec( QString("select sortorder from COMPONENT where id=%1").arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    if (query.next() == false) {
        db_.exec("ROLLBACK");
        return;
    }

    int sortorder = query.value(0).toInt();
    if (sortorder >= item->parent()->childCount()) {
        db_.exec("ROLLBACK");
        return;
    }

    // swap component
    query = db_.exec( QString("update COMPONENT set sortorder=%1 where sortorder=%2 and prodid=%3").arg(sortorder).arg(sortorder+1).arg(prodid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    query = db_.exec( QString("update COMPONENT set sortorder=%1 where id=%2").arg(sortorder+1).arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        db_.exec("ROLLBACK");
        return;
    }

    db_.exec("COMMIT");

    createComponentItems(item->parent(), compid);
}

void ComponentManagerDialog::on_treeWidget_itemChanged(QTreeWidgetItem *item, int column)
{
    if (creatingTree)
        return;

    int compid = item->data(0, Qt::UserRole).toInt();
    QString name = item->text(column);

    QSqlQuery query = db_.exec( QString("select name, japaneseName from component where id=%1").arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }
    if (query.next() == false)
        return;

    QString dbNames[] = {
        query.value(0).toString(),
        query.value(1).toString(),
    };

    if (name == dbNames[column])
        return;
    // if text is cleared, use value in db.
    else if (name.isEmpty()) {
        item->setText(column, dbNames[column]);
        return;
    }

    qDebug() << "item changed: value=" << name << ", in db=" << dbNames[column];
    query = db_.exec( QString("update COMPONENT set name='%1', japaneseName='%2' where id=%3").arg(item->text(0)).arg(item->text(1)).arg(compid) );
    if (query.lastError().isValid()) {
        qDebug() << query.lastError().text();
        return;
    }
}
